home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Mystery Science Mac / INIT sources / ShowINIT.c < prev    next >
C/C++ Source or Header  |  1993-08-24  |  14KB  |  452 lines

  1. #include "MacHeaders7"
  2. #include "Utils.h"
  3. #include "MSM.h"
  4.  
  5. #define using_MacTraps 1
  6.  
  7. #if 0
  8. ; File: ShowINIT.a
  9. ; Last Modified: Sunday, November 26, 1989 05:07:56 PM
  10. ;------------------------------------------------------------------------------------------------
  11. ;
  12. ;    INIT notification routine
  13. ;     by Paul Mercer, Darin Adler, Paul Snively and Frédéric Miserey from an idea by Steve Capps
  14. ;
  15. ;    Created:  6/7/87  PM    - First version.
  16. ;    Modified: 6/15/87 PM    - Changed to standard (Pascal) calling conventions.
  17. ;          6/20/87 PM    - Fixed color & Finder bug on Mac II.
  18. ;          6/22/87 DBA    - Improved handling of QuickDraw.
  19. ;          6/29/87 DBA    - Used scratch8 to avoid conflict with “Easy Access”.
  20. ;          6/30/87 DBA    - Changed to a 4-byte scheme with “checksum”.
  21. ;          6/30/87 PFS    - Separated into ShowINIT and InnerShowINIT.
  22. ;          7/1/87  DBA    - Fixed stack bug and switched to CurApName+.
  23. ;          7/2/87  PM    - Added check for old signature in ApplScratch for
  24. ;                          backword compatibility (TMON Startup).
  25. ;          7/3/87  PM    - Removed _SysBeep in ErrorExit since it causes a crash.
  26. ;                          Also changed ICN# plotter to srcOr mode for Blinker.
  27. ;          7/13/87 PM    - Fixed a3 trashing bug in InnerShowINIT - exit code left
  28. ;                          word on stack (reported by D. Dunham).
  29. ;          7/21/87 PM    - Due to popular demand, InitGraf is no longer being called.
  30. ;                          This avoids the gamma correction problem with Startupscreens
  31. ;                          getting  “washed out” by ShowINIT though someone else is still
  32. ;                          bound to call InitGraf sooner or later (i.e. InitWindows).
  33. ;          7/29/87 PM    - Put InitGraf back in; this is required (reported by C. Derossi
  34. ;                          at Apple Tech Support).  Took out GetPort/SetPort.
  35. ;        10/06/87  PM    - Set CurrentA5 properly.  Rearranged myVars.
  36. ;        12/28/87  PM    - Major revision to accomodate future INIT31 based ShowINIT.
  37. ;        07/14/88  PM    - Major revision to get rid of above 'accomodations'.
  38. ;                          Added color icon 'cicn' support and fixed beep crash.
  39. ;                          Removed support for old signature.
  40. ;        11/25/89 FCM    - Added Y dimension support, icl48 support to get rid of 'obsolete' cicns
  41. ;         8/28/90 jbx    - Translated to Think C, added automatic x-movement determination.
  42. ;                          Removed support for 'obsolete' cicn’s.
  43. ;
  44. ;------------------------------------------------------------------------------------------------
  45. #endif
  46.  
  47. /* Originally written by Paul Mercer.  Translated to Think C by jbx. */
  48.  
  49. typedef struct {
  50.     long    Icon[32];
  51.     long    IconMask[32];
  52. } ICONList, *ICONListPtr;
  53.  
  54. extern short myVCheck    : 0x928;    /* a GREAT place to store 8 bytes (it was Darin's idea) */
  55. extern short myV        : 0x92A;
  56. extern short myH        : 0x92C;
  57. extern short myHCheck    : 0x92E;    /* a simple checksum of myH to determine first-timeness */
  58.  
  59. enum {
  60.     firstX            =    8,            /* X coordinate of first icon to be drawn        */
  61.     bottomEdge        =    8+32,        /* this far from bottom of screen                */
  62.     iconWidth        =    32,            /* size of icon (square normally)                */
  63.     defaultMoveX    =    40,            /* x default amount to move icons                */
  64.     defaultMoveY    =    40,            /* y icon line height                            */
  65.     checksumConst    =    0x1021,        /* constant used for computing checksum            */
  66.  
  67.     iconRowBytes    =    32/8,        /* 32/8 bits                                    */
  68.  
  69.     hasCQDBit        =    6,            /* this bit in ROM85 is cleared if Color QuickDraw is available */
  70.  
  71.     iconID            =    6+4,        /* positive stackframe objects */
  72.     moveX            =    4+4,        /* horizontal distance between ShowINIT icons. */
  73.     showINITArgs    =    4,
  74.  
  75.     iconPtr            =    6+4,
  76.     initDrawArgs    =    6,
  77.  
  78.     iclPtrHdl        =    12+4,
  79.     iclDepth        =    10+4,
  80.     initDrawXArgs    =    initDrawArgs+6
  81. };
  82.  
  83. #ifndef using_MacTraps
  84. static struct {
  85.     char    qd_privates[76];    /* known only to Apple and MacWEEK... */
  86.     long    qd_randSeed;
  87.     BitMap    qd_screenBits;
  88.     Cursor    qd_arrow;
  89.     Pattern    qd_dkGray;
  90.     Pattern    qd_ltGray;
  91.     Pattern    qd_gray;
  92.     Pattern    qd_black;
  93.     Pattern    qd_white;
  94.     GrafPtr    qd_thePort;
  95. } qd;
  96.  
  97. #define thePort        qd.qd_thePort
  98. #define white        qd.qd_white
  99. #define black        qd.qd_black
  100. #define gray        qd.qd_gray
  101. #define ltGray        qd.qd_ltGray
  102. #define dkGray        qd.qd_dkGray
  103. #define arrow        qd.qd_arrow
  104. #define screenBits    qd.qd_screenBits
  105. #define randSeed    qd.qd_randSeed
  106. #endif
  107.  
  108. static long        saveA5;
  109. static long        localA5;
  110.  
  111. static Rect srcRect = {0,0,32,32};    /* for copybits */
  112. static Rect    destRect= {0,0,32,32};
  113.  
  114. static BitMap myBitMap = {
  115.     0,                /* address */
  116.     iconRowBytes,    /* rowBytes */
  117.     0,0,32,32        /* Rect */
  118. };
  119. static BitMap myMaskMap = {
  120.     0,                /* address */
  121.     iconRowBytes,    /* rowBytes */
  122.     0,0,32,32        /* Rect */
  123. };
  124. static GrafPort    myPort;
  125.  
  126.  
  127. static pascal void INITDraw1Bit(ICONListPtr iconPtr);
  128. static pascal void INITDrawCQD(CIconHandle);
  129. static pascal void INITDrawXBit(void *icl_Ptr, short iclDepth, ICONListPtr iconPtr);
  130.  
  131. /***************************************************************************************\
  132. |                                                                                        |
  133. |    Displays the ICN# (cicn when in 4 bit mode or higher) specified by iconID.            |
  134. |                                                                                        |
  135. |    PROCEDURE ShowINIT(iconID: Integer); EXTERNAL;                                        |
  136. |                                                                                        |
  137. |    pascal void ShowINIT(short iconID);                                                    |
  138. |        extern;                                                                            |
  139. |                                                                                        |
  140. \***************************************************************************************/
  141.  
  142. pascal void ShowINIT(short iconID) {
  143.     register void *Addr3, *Addr2;
  144.     register long Data7, Data6, Data5, Data4, Data3;
  145.  
  146.     asm {
  147. ShowINIT:
  148.  
  149.         btst.b    #hasCQDBit,ROM85    ; try to get a color icon if CQD exists
  150.         beq        @ShowINITCQD        ; I could use SysEnvirons but I don't want to
  151.  
  152. ShowINIT1Bit:
  153.         clr.l    -(sp)                ; try to get the icon resource
  154.         move.l    #'ICN#',-(sp)
  155.         move.w    iconID(a6),-(sp)
  156.         GetResource
  157.         move.l    (sp)+,d0
  158.         beq        @ShowINITError        ; can't get it, give up
  159.  
  160.         move.l    d0,-(sp)            ; leave handle on the stack for ReleaseResource
  161.         move.l    d0,a0
  162.         HLock
  163.         move.l    (a0),a0                ; dereference
  164.         move.l    a0,-(sp)            ; icon pointer
  165.         jsr        INITDraw1Bit        ; draw
  166.         ReleaseResource                ; release the resource
  167.         return
  168.  
  169. ShowINITCQD:
  170.         move.l    #0x40008,d2
  171.         move.l    #'icl8',d3
  172.         move.l    #'icl4',d4
  173.         move.l    MainDevice,a0        ; get handle to main device
  174.         move.l    (a0),a0                ; dereference
  175.         move.l    OFFSET(GDevice, gdPMap)(a0),a0
  176.                                     ; get its pixmap handle
  177.         move.l    (a0),a0                ; dereference it
  178.         cmpi.w    #4,OFFSET(PixMap,pixelSize)(a0)
  179.                                     ; is it deep enough for us to draw with icl4?
  180.         blt.s    @ShowINIT1Bit        ; no, go to 1-bit.
  181.                                     ; is it deep enough for us to draw with icl8?
  182.         beq.s    @SwapOrder            ; no, swap order.
  183.  
  184. tryAgain:
  185.         clr.l    -(sp)
  186.         move.l    d3,-(sp)
  187.         move.w    iconID(a6),-(sp)
  188.         GetResource
  189.         move.l    (sp)+,d1
  190.         bne.s    @FoundIc
  191.  
  192.         clr.w    d2
  193. SwapOrder:
  194.         swap    d2
  195.         beq        @tryCICN
  196.         exg        d3,d4
  197.         bra.s    @tryAgain
  198.  
  199. tryCICN:
  200.         goto    ShowINIT1Bit
  201.  
  202. FoundIc:
  203.         clr.l    -(sp)
  204.         move.l    #'ICN#',-(sp)
  205.         move.w    iconID(a6),-(sp)
  206.         GetResource
  207.         move.l    (sp)+,d0
  208.         bne.s    @FoundCompanion
  209.  
  210.         move.l    d1,-(sp)
  211.         ReleaseResource
  212.         bra        @tryCICN
  213.  
  214. FoundCompanion:        
  215.         move.l    d1,-(sp)        ; leave handle on the stack for ReleaseResource
  216.         move.l    d0,-(sp)        ; leave handle on the stack for ReleaseResource
  217.         move.l    d0,d3
  218.  
  219.         move.l    d1,a0
  220.         HLock
  221.         move.l    (a0),a0            ; dereference
  222.         move.l    a0,-(sp)        ; icl_ pointer
  223.         move.w    d2,-(sp)        ; icl_ depth
  224.         move.l    d3,a0
  225.         HLock
  226.         move.l    (a0),a0            ; dereference
  227.         move.l    a0,-(sp)        ; icon pointer
  228.         jsr        INITDrawXBit    ; draw
  229.         ReleaseResource        ; release the resource
  230.         ReleaseResource        ; release the resource
  231.         return
  232.  
  233. ShowINITError:
  234.         move.w    #8,-(sp)            ; just beep
  235.         SysBeep
  236.         return
  237.     }
  238. }
  239.  
  240. static void ShowINITCredits(void) {
  241.     asm {
  242.         dc.b    "ShowINIT by Paul Mercer"    ,0
  243.         dc.b    "Copyright 1987-1989"        ,0
  244.         dc.b    "Version of 11/25/89"        ,0
  245.         dc.b    "Modified by jbx 8/28/90"    ,0
  246.     };
  247. }
  248.  
  249. /***************************************************************************************\
  250. |                                                                                        |
  251. |    Initializes the world and sets up the drawing rectangle                                |
  252. |                                                                                        |
  253. \***************************************************************************************/
  254.  
  255. static void INITInit(void) {
  256.     asm {
  257.         move.l    CurrentA5,saveA5    ; PM 10/6 save host A5
  258.         lea        localA5,a5            ; PM7/21
  259.         move.l    a5,CurrentA5
  260.         pea        thePort                ; PM 10/6 use a5 reference instead of a6
  261.         InitGraf                    ; fixes color bug as per DA@ICOM
  262.         pea        myPort
  263.         OpenPort
  264.  
  265.         move.w    myV,d0            ; get my v var
  266.         rol.w    #1,d0            ; compare against checksum
  267.         eor.w    #checksumConst,d0
  268.         cmp.w    myVCheck,d0
  269.         beq.s    @ScratchVOK        ; checks, so go on test my h var
  270.  
  271.         move.w    myPort.portBits.bounds.bottom,d0 ; else initialize as first time
  272.         sub.w    #bottomEdge,d0
  273.         move    d0,myV
  274. ScratchVOK:
  275.         move.w    myH,d0            ; get my h var
  276.         rol.w    #1,d0            ; compare against checksum
  277.         eor.w    #checksumConst,d0
  278.         cmp.w    myHCheck,d0
  279.         beq.s    @ScratchHOK        ; checks, so go on
  280.         move    #firstX,myH        ; else initialize as first time
  281. ScratchHOK:
  282.         move.l    myV,d0            ; trickery - high word is V, lo word is H.
  283.  
  284.         move.w    d0,d1            ; get future position
  285.         add.w    #iconWidth,d1    ; compute future rect right
  286.         cmp.w    myPort.portBits.bounds.right,d1 ; compare to main screen right
  287.         blt.s    @DontChangeLine    ; smaller - do nothing
  288.  
  289.         move.w    myV,d0            ; decrement Y value
  290.         subi.w    #defaultMoveY,d0
  291.         move.w    d0,myV
  292.         move.w    #firstX,myH        ; set X to initial value
  293.  
  294.         move.l    myV,d0
  295. DontChangeLine:
  296.         lea        destRect,a0
  297.         move.l    d0,(a0)+
  298.         move.l    d0,(a0)
  299.     }
  300. }
  301.  
  302. /***************************************************************************************\
  303. |                                                                                        |
  304. |    Based on the mask, advances the icon drawing position and adjusts destRect            |
  305. |                                                                                        |
  306. \***************************************************************************************/
  307.  
  308. static void MaskAdjust(void) {
  309.     asm {
  310.         lea        myMaskMap,a0
  311.         move.l    (a0)+,a1        ; baseAddr
  312.         move.w    (a0)+,d0        ; rowBytes
  313.         move.w    4(a0),d1        ; bottom
  314.         move.w    6(a0),d2        ; right
  315.         sub.w    (a0)+,d1        ; top - d1 now has height.
  316.         sub.w    (a0)+,d2        ; left - d2 now has width.
  317.         add.w    d1, destRect.bottom
  318.         add.w    d2, destRect.right
  319.         cmpi.w    #4,d0            ; is rowBytes 4? Might not be on a color icon!
  320.         beq.s    @four
  321.         add.w    d2,myH            ; so assume the icon is properly done,
  322.         goto    done            ; without any mask holes.
  323.     four:
  324.         add.w    #32,myH            ; assume the icon is normal.
  325.         moveq    #0,d0            ; d0 accumulates the mask columns.
  326.         subq.w    #1,d1
  327.         bmi.s    @out            ; oops, no height, we're outa here.
  328.  
  329.     ol:    or.l    (a1)+,d0
  330.         dbra    d1,    @ol
  331.  
  332.         ; OK, now d0's bits correspond to the columns of the mask.
  333.         ; make sure there really is a mask...
  334.         tst.l    d0
  335.         bne.s    @lft
  336.     out:return            ; and if not, we're outa here!
  337.  
  338.         ; first thing, we shift the icon to the left for every empty high bit:
  339.     ll:    subq.w    #1,destRect.left
  340.         subq.w    #1,destRect.right
  341.         asl.l    #1,d0
  342.     lft:bpl.s    @ll
  343.  
  344.         ; OK, now the icon is properly positioned.  Now we check for empty space on
  345.         ; on the right, which we can use to properly figure the destination rectangle:
  346.     rl:    ror.l    #1,d0
  347.         bmi.s    @done
  348.         subq.w    #1,myH
  349.         bra.s    @rl
  350.     }
  351.     done:
  352.         myH += 8;
  353. }
  354.  
  355. /***************************************************************************************\
  356. |                                                                                        |
  357. |    Cleans up the work done by INITInit and advances the icon drawing position            |
  358. |                                                                                        |
  359. \***************************************************************************************/
  360.  
  361. static void INITCleanup(void) {
  362.     asm {
  363.         move.w    myH,d0            ; get current position
  364.         rol.w    #1,d0            ; recompute h checksum
  365.         eor.w    #checksumConst,d0
  366.         move.w    d0,myHCheck        ;  and save it
  367.  
  368.         move    myV,d0            ; same for v checksum
  369.         rol.w    #1,d0
  370.         eor.w    #checksumConst,d0
  371.         move.w    d0,myVCheck
  372.  
  373.         pea        myPort            ; *** (DBA) I think that QuickDraw leaves handles around.
  374.         ClosePort                ; *** (DBA) Too bad we can't get rid of them...
  375.  
  376.         move.l    saveA5,a5        ; PM 10/6 restore host A5
  377.         move.l    a5,CurrentA5
  378.     }
  379. }
  380.  
  381. /***************************************************************************************\
  382. |                                                                                        |
  383. |    display the ICN# pointed to by iconPtr and move the pen horizontally by moveX        |
  384. |     pass a -1 in moveX to move the standard amount, moveX should be 40 for most ICN#'s    |
  385. |                                                                                        |
  386. |    PROCEDURE INITDraw1Bit(iconPtr: ICONListPtr); EXTERNAL                                |
  387. |                                                                                        |
  388. |    pascal void INITDraw1Bit(ICONListPtr iconPtr);                                        |
  389. |                                                                                        |
  390. \***************************************************************************************/
  391.  
  392. static pascal void INITDraw1Bit(ICONListPtr iconPtr) {
  393.     INITInit();            /* initialize for drawing. */
  394.  
  395.     myBitMap.baseAddr  = (void *)iconPtr->Icon;
  396.     myMaskMap.baseAddr = (void *)iconPtr->IconMask;
  397.  
  398.     MaskAdjust();
  399.  
  400.     CopyMask(&myBitMap, &myMaskMap, &myPort.portBits, &srcRect, &srcRect, &destRect);
  401.  
  402.     INITCleanup();    /* cleanup, advance icon location */
  403. }
  404.  
  405.  
  406. /***************************************************************************************\
  407. |                                                                                        |
  408. |    display the Icl pointed to by iclPtr and move the pen horizontally by moveX            |
  409. |     pass a -1 in moveX to move the standard amount, moveX should be 40 for most ICN#'s    |
  410. |                                                                                        |
  411. |    PROCEDURE INITDrawXBit(iclPtr: icl_Ptr; iclDepth: Integer;                             |
  412. |                iconPtr: ICONListPtr); EXTERNAL;                                        |
  413. |                                                                                        |
  414. |    pascal void INITDrawXBit(icl_Ptr, iclDepth, moveX)                                    |
  415. |        icl_Ptr *iclPtr;                                                                |
  416. |        short iclDepth;                                                                    |
  417. |        ICONList *iconPtr;                                                                |
  418. |        extern;                                                                            |
  419. |                                                                                        |
  420. \***************************************************************************************/
  421.  
  422. static pascal void INITDrawXBit(void *icl_Ptr, R short iclDepth, ICONListPtr iconPtr) {
  423.     PixMapHandle pmh;
  424.     R PixMapPtr pmp;
  425.  
  426.     if (!(pmh = NewPixMap())) {
  427.         INITDraw1Bit(iconPtr);
  428.     } else {
  429.         INITInit();            /* initialize for drawing */
  430.         HLock(pmh);
  431.         pmp = *pmh;
  432.         DisposHandle(pmp->pmTable);
  433.         pmp->pmTable = (CTabHandle) RGetResource('clut', iclDepth);
  434.         pmp->baseAddr = icl_Ptr;
  435.         pmp->rowBytes = 0x8000 | (iclDepth * iconRowBytes);
  436.         pmp->bounds = srcRect;
  437.         pmp->pixelType = chunky;
  438.         pmp->pixelSize = iclDepth;
  439.         pmp->cmpCount = 1;
  440.         pmp->cmpSize = iclDepth;
  441.  
  442.         myMaskMap.baseAddr = (void *)iconPtr->IconMask;
  443.         MaskAdjust();
  444.         
  445.         CopyMask(pmp, &myMaskMap, &myPort.portBits, &srcRect, &srcRect, &destRect);
  446.  
  447.         pmp->pmTable = (void *)NewHandle(0);
  448.         DisposPixMap(pmh);
  449.  
  450.         INITCleanup();        /* cleanup, advance icon location */
  451.     }
  452. }